package com.tangding.hprose.filters;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;

import hprose.common.HproseContext;
import hprose.common.HproseFilter;
import hprose.io.ByteBufferStream;

/**
 * @description 
 *
 * @author Ranger
 * @version 2017年11月21日_下午2:04:17
 *
 */
public class SessionFilter implements HproseFilter {
	
	static class Session {
        final static IdentityHashMap<HproseContext, Integer> sidMap = new IdentityHashMap<HproseContext, Integer>();
        final static ArrayList<HashMap<String, Object>> sessions = new ArrayList<HashMap<String, Object>>();
        public static HashMap<String, Object> getSession(HproseContext context) {
           	return sessions.get(sidMap.get(context));
        }
    }

	@Override
    public ByteBuffer inputFilter(ByteBuffer istream, HproseContext context) {
        int len = istream.limit() - 7;
        if (len > 0 &&
            istream.get() == 's' &&
            istream.get() == 'i' &&
            istream.get() == 'd') {
            int sid = ((int)istream.get()) << 24 |
                      ((int)istream.get()) << 16 |
                      ((int)istream.get()) << 8  |
                       (int)istream.get();
            Session.sidMap.put(context, sid);
            return istream.slice();
        }
        int sid = Session.sessions.size();
        Session.sidMap.put(context, sid);
        Session.sessions.add(new HashMap<String, Object>());
        istream.rewind();
        return istream;
    }

    @Override
    public ByteBuffer outputFilter(ByteBuffer ostream, HproseContext context) {
        int sid = Session.sidMap.get(context);
        ByteBuffer buf = ByteBufferStream.allocate(ostream.remaining() + 7);
        buf.put((byte)'s');
        buf.put((byte)'i');
        buf.put((byte)'d');
        buf.put((byte)(sid >> 24 & 0xff));
        buf.put((byte)(sid >> 16 & 0xff));
        buf.put((byte)(sid >> 8 & 0xff));
        buf.put((byte)(sid & 0xff));
        buf.put(ostream);
        ByteBufferStream.free(ostream);
        return buf;
    }
}
